/**
 * Created by Administrator on 2017/1/15.
 */
var pomelo = require('pomelo');
var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var Const = require('./const');
var SubCode = require('../subCode');
var gameUtil = require("../../../util/gameUtil");

exports.HLMJRoom = MJRoom.extend({

    _lastWinPlay : 0,
    _piaoStatus: Const.PiaoStatus.None,
    _maCard: [],

    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);

        this._lastWinPlay = 0;
        this._piaoStatus = Const.PiaoStatus.None;
        this._maCard = [];

        this.setSaveReplay(true);
    },

    isSelectedPiao : function () {
        return this.getOption("isAddPiao");
    },

    isSelectPiaoFinished : function () {
        return this._piaoStatus == Const.PiaoStatus.Finish;
    },

    selectZhuang : function () {

        if (this.getCurRound() == 1) {
            this._dealerIndex = 1;
        } else {
            // 上局赢家就是庄
            this._dealerIndex = this._lastWinPlay;
        }

        var player = this.getDealerPlayer();
        if (this._dealerIndex == this._lastWinPlay) {
            player.addDealerCount();
        }
    },

    buyMaInterface : function (player, huCard) {

        var buyMaStatus = clone(this.getOption("isBuyMa"));

        // 根据当前房间选择的规则进行买马
        // 不买马
        if ( buyMaStatus == 0 ) {
            return false;
        }

        // 判断亮倒自摸买马
        var buyMaCondition = (buyMaStatus / 10) >= 2;
        if (buyMaCondition && !player.isBaoTing()) {
            return false;
        }

        // 获取买马的规则， 并进行对应的结算
        var card = huCard;
        if (buyMaStatus % 10 == 2) {
            // 147买码
            card = this.get147BuyCardRule (player, huCard);
            this._maCard = card;
        }else {
            // 经典买码
            this.getCurstomCardRule (player, huCard);
            this._maCard.push (card);
        }

        //// 发送当前的买马牌值告诉客户端
        //this.broadcast("buMaCard", {
        //    length: length,
        //    card: card
        //}.bind(this));

        return true;
    },

    /**
     * 对对应玩家进行147买码处理
     * 并回传最后的五张牌
     * @param player
     * @param huCard
     * @returns {Array}
     */
    get147BuyCardRule : function (player, huCard) {

        // 获取最后的五张牌
        var card = [];

        var remainCards = clone(this._publicCards.getRemainCards());

        // 判断当前剩余的牌数是否够五张,不够的话, 用空白表示,并默认中码
        if (remainCards.length <= Const.gameSetting.MaNum) {
            card = remainCards;
        }else {

            // 如果大于五张，则从剩余牌中获取最后五张
            var length = remainCards.length;

            for (var index = length - 1; index >= remainCards.length - Const.gameSetting.MaNum; --index) {
                card.push (remainCards[index]);
            }
        }

        // 判断特殊牌型
        var huPoint = -1;
        switch (huCard) {
            case MJ.ZI.BB: huPoint = 0; break;
            case MJ.ZI.HZ: huPoint = 1; break;
            case MJ.ZI.FC: huPoint = 2; break;
        }

        // 根据当前玩家胡牌判断是147, 还是258，或者369
        var specRule = false;
        if (huPoint == -1) {
            huPoint = MJ.getPoint(huCard);
        }else {
            specRule = true;
        }

        // 规则 0表示 369 1表示147 2表示258
        var rule = huPoint % 3;

        // 中码数
        var maNum = 0;
        for (var index = 0; index < Const.gameSetting.MaNum; ++index) {

            if (card[index]) {

                var maPoint;

                // 获取码数
                if (specRule) {

                    switch (card[index]) {
                        case MJ.ZI.BB: maPoint = 0; break;
                        case MJ.ZI.HZ: maPoint = 1; break;
                        case MJ.ZI.FC: maPoint = 2; break;
                        default: maPoint = MJ.getPoint(card[index]) % 3;break;
                    }

                }else {

                    switch (card[index]) {
                        case MJ.ZI.BB:
                        case MJ.ZI.HZ:
                        case MJ.ZI.FC: maPoint = 3; break;
                        default: maPoint = MJ.getPoint(card[index]) % 3;break;
                    }
                }

                // 表示中码
                if (maPoint == 3 || rule == maPoint) {
                    maNum += 1;
                }
            }else {
                maNum += 1;
            }
        }

        player.setMaScore(maNum);

        return card;
    },

    /**
     * 对对应经典买马玩家进行买马中码确认
     * @param player
     * @param huCard
     */
    getCurstomCardRule : function (player, huCard) {

        // 获取胡牌的点数
        var huPoint;

        if (huCard == MJ.ZI.HZ
            || huCard == MJ.ZI.BB
            || huCard == MJ.ZI.FC) {
            huPoint = 10;
        }

        // 普通牌获取码
        if (!huPoint) {
            huPoint = MJ.getPoint(huCard);
        }

        player.setMaScore (huPoint);
    },

    /**
     * 结算黄庄
     */
    onSettlementHZ : function () {

        this._lastWinPlay = this.getDealerIndex();

        // 查看是否所有玩家都叫牌
        var isAllPlayerTing = true;
        var winP = [];
        var failP = [];
        var baoTingP = [];
        var noBaoTingP = [];

        this.enumPlayers(function (eIndex, ePlayer) {

            if (ePlayer) {

                // 黄庄的话 检测所有玩家的最大牌型
                ePlayer.checkSettlementPattern();

                if (ePlayer.getRoundPattern() != Const.Pattern.NONE) {
                    winP.push (ePlayer);
                }else {
                    failP.push (ePlayer);
                    isAllPlayerTing = false;
                }

                if (ePlayer.isBaoTing()) {
                    baoTingP.push (ePlayer);
                }else {
                    noBaoTingP.push (ePlayer);
                }
            }
        }.bind (this));

        if (isAllPlayerTing) {
            for (var nIndex = 0; nIndex < noBaoTingP.length; ++nIndex) {

                var nBaoPlayer = noBaoTingP[nIndex];
                for (var Index = 0; Index < baoTingP.length; ++Index) {

                    var baoPlayer = baoTingP[Index];
                    nBaoPlayer.addRoundItemScores("huangZhuang", baoPlayer.getRoundPatternScore());
                    baoPlayer.addRoundItemScores(baoPlayer.getRoundPattern(), -baoPlayer.getRoundPatternScore())
                }
            }
        }
        // 所有失败玩家减少对应玩家的分数
        else {
            for (var fIndex = 0; fIndex < failP.length; ++fIndex) {

                var failPlayer = failP[fIndex];
                for (var wIndex = 0; wIndex < winP.length; ++wIndex) {

                    var winPlayer = winP[wIndex];
                    failPlayer.addRoundItemScores("huangZhuang", -winPlayer.getRoundPatternScore());
                    winPlayer.addRoundItemScores(winPlayer.getRoundPattern(), winPlayer.getRoundPatternScore())
                }
            }
        }
    },

    /**
     * 获取当前限制的最大分数
     * @param score
     * @returns {*}
     */
    getMaxFanScore : function (score) {

        if (this.getOption("topFanRate") < score) {
            return this.getOption("topFanRate");
        }

        return score;
    },

    /**
     * 获取胡牌玩家的最大牌型分
     * @param player
     * @param rules
     * @returns {*}
     */
    getMaxRoundPatternScore : function (player, rules, card, pattern) {

        if (player.getRoundHuCard()) {
            pattern = player.checkHuPatternWithCard (player.getRoundHuCard(), pattern);
        }else if (card){
            pattern = player.checkHuPatternWithCard (card, pattern);
        }

        var patternScore = player.getPatternScore(pattern);

        // 这个是检测是否可以胡牌使用的
        if (rules && rules.length >= 1) {

            for (var rule = 0; rule < rules.length; ++rule) {

                switch (rules[rule]) {
                    case Const.ScoreRule.QG : {
                        patternScore = this.getMaxFanScore (patternScore * 2);
                    } break;
                    case Const.ScoreRule.GSH : {
                        if (this.getOption("isGangShangHua")) {
                            patternScore = this.getMaxFanScore (patternScore * 4);
                        } else {
                            patternScore = this.getMaxFanScore (patternScore * 2);
                        }
                    } break;
                    case Const.ScoreRule.GSP : {
                        patternScore = this.getMaxFanScore (patternScore * 2);
                    } break;
                    case Const.ScoreRule.ZM : {
                        patternScore = this.getMaxFanScore (patternScore * 2);
                    }break;
                }
            }
        }
        // 这边适用于总结算使用的
        else {

            if (player.existRoundScoreRule(Const.ScoreRule.QG)) {
                patternScore = this.getMaxFanScore (patternScore * 2);
            }

            if (player.existRoundScoreRule(Const.ScoreRule.GSH)) {
                if (this.getOption("isGangShangHua")) {
                    patternScore = this.getMaxFanScore (patternScore * 4);
                } else {
                    patternScore = this.getMaxFanScore (patternScore * 2);
                }
            }

            // 如果是杠上炮
            if (player.existRoundScoreRule(Const.ScoreRule.GSP)) {
                patternScore = this.getMaxFanScore (patternScore * 2);
            }

            if (player.isZm()) {
                patternScore = this.getMaxFanScore (patternScore * 2);
            }
        }

        if (player.isBaoTing()) {
            patternScore = this.getMaxFanScore (patternScore * 2);
        }

        return {patternScore : patternScore, pattern : pattern};
    },

    /**
     * 正常结算
     */
    onSettlementHuCard : function (playerIndex) {

        // 需要逐玩家结算分数
        var huPlayer = this.getPlayerByIndex(playerIndex);

        this._lastWinPlay = huPlayer.getIndex();

        var pattern = huPlayer.getRoundPattern();
        var patternResult = clone (this.getMaxRoundPatternScore (huPlayer, null, null, pattern));
        huPlayer.setRoundPattern(patternResult.pattern, patternResult.patternScore);

        var hupiao = 0;
        if (this.isSelectedPiao()) {
            hupiao = clone (huPlayer.getSelectPiao());
        }

        var huKan = 0;
        if (this.getOption("isNumKan")) {
            huKan = clone (huPlayer.getHandKan());
        }

        var ma = 0;
        if (this.getOption("isBuyMa") != 0) {
            ma = huPlayer.getMaScore();
        }

        var huScores = 0;
        var maScores = 0;
        var piaoScores = 0;
        var kanScores = 0;

        this.enumPlayers(function (eIndex, ePlayer) {

            if (ePlayer && eIndex != playerIndex) {

                var checkPatternScore = clone(patternResult.patternScore);

                if (huPlayer.getRoundResult() == 1 && ePlayer.getRoundResult() != -1) {
                    return;
                }

                if (!huPlayer.isBaoTing() && ePlayer.isBaoTing()) {
                    checkPatternScore = this.getMaxFanScore (checkPatternScore * 2);
                }

                ePlayer.addRoundItemScores(huPlayer.getRoundPattern(), -checkPatternScore);
                huScores += checkPatternScore;

                if (this.isSelectedPiao()) {
                    var playerPiao = ePlayer.getSelectPiao() + hupiao;
                    ePlayer.addRoundItemScores("piao", -playerPiao);
                    piaoScores += playerPiao;
                }

                if (this.getOption("isNumKan")) {
                    ePlayer.addRoundItemScores("kan", -huKan);
                    kanScores += huKan;
                }

                if (this.getOption("isBuyMa") != 0) {
                    ePlayer.addRoundItemScores("ma", -ma);
                    maScores += ma;
                }
            }
        }.bind (this));

        huPlayer.addRoundItemScores(huPlayer.getRoundPattern(), huScores);
        huPlayer.addRoundItemScores("piao", piaoScores);
        huPlayer.addRoundItemScores("kan", kanScores);
        huPlayer.addRoundItemScores("ma", maScores);
    },

    preStartPlay: function() {
        this.initPlayersHandCards();
        this.startPlay();
    },

    _startPlay : function () {
        this._changeCurPlay(this.getDealerIndex());
        this._doCheckNewCardHangupTask();
    },

    /**
     * 添加连杠参数
     * @param gangArray
     */
    addLGNum : function (gangArray) {
        var gangNum = this._curGang + 1;

        if (ExObject.isArray(gangArray)) {

            for (var index = 0; index < gangArray.length; ++index) {
                gangArray[index].gangRate = gangNum;
            }
        }else {
            gangArray.gangRate = gangNum;
        }
    },

    /**
     * 结算单次杠分
     * @param player
     * @param gangInfo
     */
    settlementOnceGangScore : function (player, gangInfo) {

        var gangRate = 1;
        if (gangInfo.gangRate) {
            for (var index = 1; index < gangInfo.gangRate; ++index) {
                gangRate *= 2;
            }
        }

        // 在此处计算杠分 (查看是否合适)
        var targetPlayer = this.getPlayerByIndex (gangInfo.from);
        var gang = gangInfo.gang;
        var gangScore = Const.GangScore[gang] * gangRate;

        if (gangRate > 1) {
            player.setRoundScoreRule(Const.ScoreRule.GSG);
        }

        if (gang == MJ.Gang.DIAN) {
            player.addGangScore(gangScore);
            player.setGangRate(gangRate);

            targetPlayer.addGangScore(-gangScore);
            targetPlayer.setRoundScoreRule(gang);
            targetPlayer.setGangRate(gangRate);
        }else if (gang == MJ.Gang.BA || gang == MJ.Gang.AN || gang == MJ.Gang.ANS) {
            this.enumPlayers (function(eIndex, ePlayer) {
                if (ePlayer) {
                    ePlayer.setGangRate(gangRate);

                    if (eIndex == player.getIndex()) {
                        ePlayer.setRoundScoreRule(gang);
                        ePlayer.addGangScore(gangScore * (this.getSubConfig().roomPlayerNum - 1));
                    }else {
                        ePlayer.addGangScore(-gangScore);
                    }
                }
            }.bind(this));
        }
    },

    /**
     * 结算当局中所有玩家的杠分
     */
    settlementGangScore : function () {

        // 逐个获取杠信息，并进行结算
        this.enumPlayers( function (eIndex, ePlayer) {

            if (ePlayer) {

                // 获取玩家的杠信息
                var gangInfoCards = ePlayer.getGangCards ();

                if (gangInfoCards.length > 0) {
                    for (var index = 0; index < gangInfoCards.length; ++index) {
                        var gangInfo = gangInfoCards[index];

                        this.settlementOnceGangScore(ePlayer, gangInfo);
                    }
                }
            }
        }.bind(this));

     },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    onBeforeStartNewRound: function() {
        this._super();

        this._maCard = [];
        this.selectZhuang();
    },

    onAfterStartNewRound : function () {
        this._super();

        if (!this.isSelectedPiao() || this.isSelectPiaoFinished() || this.getCurRound() != 1) {
            this.preStartPlay();
        }
    },

    getReconnectInfo : function (rePlayer) {
        var info = this._super (rePlayer);
        info.piaoStatus = this._piaoStatus;
        return info;
    },

    getSettlementInfo : function () {
        var info = this._super ();

        info.maCards = this._maCard;
        return info;
    },

    /******************************************************************
     * 需要重载的接口
     ******************************************************************/

    /**
     * 开始一局
     */
    startPlay: function() {

        //var dealer = this.getDealerIndex();
        //
        //this.enumPlayers(function(eIndex, ePlayer) {
        //    if (eIndex != dealer) {
        //        var tings = ePlayer.checkTing();
        //        if (tings.length == 1) {
        //            this._hangupTask.addTingTask(eIndex, tings);
        //        }
        //        ePlayer.setTingCards(tings);
        //    }
        //}.bind(this));
        logger.debug("room=%d sendHangupTask in=HLMJ.startPlay", this.rid());

        this._sendHangupTask(this._startPlay);
    },

    checkNewCardHangupTask: function() {
        var player = this.getCurPlayer();

        var huIndexs = [];
        var huPattern = player.checkHu();
        if (huPattern != Const.Pattern.NONE) {
            var rules = [];
            if (this.getCurGang()) {
                rules.push(Const.ScoreRule.GSH);
            }

            // 检测当前是否是自摸
            rules.push (Const.ScoreRule.ZM);

            // 番的分数大于二才行
            var card = player.getLastCard() || player.getInitLastCard();
            var patternResult = this.getMaxRoundPatternScore (player, rules, card, huPattern);

            if (patternResult.patternScore >= 2) {
                var pattern = patternResult.pattern;
                this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), pattern, rules);
                huIndexs.push(player.getIndex());
            }
        }

        var gangArray = player.checkGang();
        if (gangArray.length > 0 && player.isBaoTing()) {
            var newGangArray = [];
            for (var i = 0; i < gangArray.length; ++i) {
                if (!player.checkTingChangeIfGang(gangArray[i])) {
                    newGangArray.push(gangArray[i]);
                }
            }
            gangArray = newGangArray;
        }

        if (gangArray.length > 0 && this.getPublicCards().getRemainNum() > 0) {

            // 获取当前的连杠次数
            this.addLGNum (gangArray);

            this._hangupTask.addGangTask(player.getIndex(), gangArray);
        }

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },

    checkCurPlayHangupTask: function() {
        this._super();

        var player = this.getCurPlayer();
        if (!player.isBaoTing()) {
            var gangArray = player.checkGang();
            if (gangArray.length > 0 && this.getPublicCards().getRemainNum() > 0) {
                // 获取当前的连杠次数
                this.addLGNum (gangArray);

                this._hangupTask.addGangTask(player.getIndex(), gangArray);
            }
        }
    },

    /**
     * 出牌之后检测任务
     * @param card
     */
    checkPlayCardHangupTask: function(card) {

        //var player = this.getCurPlayer();
        //
        //if (!player.isBaoTing()) {
        //    var tings = player.checkTing();
        //    if (tings.length >= 1 && this.getPublicCards().getRemainNum() >= 12) {
        //        this._hangupTask.addTingTask(player.getIndex(), tings);
        //        player.setTingCards(tings);
        //    }
        //}

        this._checkPlayCardHangupTask(card);
    },

    _checkPlayCardHangupTask: function(card) {
        var curPlay = this.getCurPlay();

        var curPlayer = this.getCurPlayer();
        if (!curPlayer.getLastCard() || curPlayer.getLastCard() != card) { // 不是打的上次摸的牌，则重新检查听牌
            var tings = curPlayer.checkTing();
            curPlayer.setTingCards(tings);
        }

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != curPlay && !ePlayer.isRoundHu()) {
                if (!ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                    var huPattern = ePlayer.checkHuWithCard(card);
                    if (huPattern != Const.Pattern.NONE) {
                        var rules = [];
                        if (this.getCurGang() > 0) {
                            var gangInfo = curPlayer.getLastGang();
                            if (gangInfo && this.checkGangNewCard(gangInfo)) {
                                rules.push(Const.ScoreRule.GSP);
                            }
                        }

                        // 番的分数大于二才行
                        var patternResult = this.getMaxRoundPatternScore (ePlayer, rules, card, huPattern);

                        if (patternResult.patternScore >= 2) {
                            var pattern = patternResult.pattern;
                            this._hangupTask.addHuTask(eIndex, card, curPlay, pattern, rules);
                            huIndexs.push(eIndex);
                        }
                    }
                }

                if (!ePlayer.isBaoTing()) {
                    if (ePlayer.checkPengWithCard(card)) {
                        this._hangupTask.addPengTask(eIndex, card, curPlay);
                    }
                }

                if (ePlayer.checkGangWithCard(card)) {
                    var gangTask = {card: card, from: curPlay, gang: MJ.Gang.DIAN};
                    if (ePlayer.isBaoTing()) {
                        if (ePlayer.checkTingChangeIfGang(gangTask)) {
                            gangTask = null;
                        }
                    }

                    if (gangTask && this.getPublicCards().getRemainNum() > 0) {

                        // 获取当前的连杠次数
                        this.addLGNum (gangTask);

                        this._hangupTask.addGangTask(eIndex, [gangTask]);
                    }
                }
            }
        }.bind(this));

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },

    /**
     * 出牌前检测
     * @param player
     * @param msg
     * @returns {Number} 错误码
     */
    onBeforePlayCard: function(player, msg, card) {
        var code = this._super();

        if (code) {
            return code;
        }

        if (this.isSelectedPiao() && this.getCurRound() == 1
            && this._piaoStatus != Const.PiaoStatus.Finish) {
            return Code.DB_ERROR;
        }
    },

    /**
     * 出牌之后检查
     * @param player
     * @param card
     * @param playInfo
     */
    onAfterPlayCard: function (player, card, playInfo) {

        this._super(player, card, playInfo);

        if (player.isBaoTing() && !player.getShowStatus()) {
            var LDResult = player.checkShowCards ();

            playInfo.LDResult = LDResult;
            playInfo.tingCard = player.getTingCards();
        }
    },

    checkGangHangupTask: function(playerIndex, gangInfo) {
        var card = gangInfo.card;

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != playerIndex && !ePlayer.isRoundHu() && !ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                var huPattern = ePlayer.checkHuWithCard(card);
                if (huPattern != Const.Pattern.NONE && this.checkGangTaskQG(null, gangInfo)) {// 抢杠
                    var rules = [];
                    rules.push(Const.ScoreRule.QG);

                    // 番的分数大于二才行
                    var patternResult = this.getMaxRoundPatternScore (ePlayer, rules, card, huPattern);

                    if (patternResult.patternScore >= 2) {
                        var pattern = patternResult.pattern;
                        this._hangupTask.addHuTask(eIndex, card, playerIndex, pattern, rules);
                        huIndexs.push(eIndex);
                    }
                }
            }
        }.bind(this));

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },

    checkGangTaskQG: function(task, gangInfo) {
        return gangInfo.gang == MJ.Gang.BA;
    },

    onHangupTaskDone: function(source, taskId) {
        this._super(source, taskId);

        if (source.task == MJ.Task.PLAY) {
            if (taskId != MJ.Task.PENG && taskId != MJ.Task.GANG && taskId != MJ.Task.HU) {
                this._lastPlayCardIndex = source.playerIndex;
            }
        }
    },

    /**
     * 检查胡牌后是否可能结算
     */
    checkHuSettlement: function() {
        this._super();
        return true;
    },

    /**
     * 胡牌处理
     * @param task
     */
    onSettlementHuTask: function(task) {

        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);

        var isZM = (playerIndex == from); // 是否是自摸

        // 计算胡牌玩家的分数情况 （分为自摸和点炮, 荒庄）
        var playerIndex = this.getFirstHuPlayerIndex();

        var targetsIndex = [];
        var targets = [];
        if (isZM) {
            this.enumPlayers(function(eIndex, ePlayer) {
                if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                    targetsIndex.push(eIndex);
                    targets.push(ePlayer);
                }
            });
        } else {
            targetsIndex.push(from);
            targets.push(this.getPlayerByIndex(from));
        }

        var patternScore = huPlayer.getPatternScore(pattern);

        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            switch (rule) {
                case Const.ScoreRule.GSH:
                    huPlayer.setRoundScoreRule(rule);
                    break;
                case Const.ScoreRule.GSP:
                    if (!isZM) {
                        huPlayer.setRoundScoreRule(rule);
                    }
                    break;
                case Const.ScoreRule.QG:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的被抢玩家一定是当前玩家

                            // 当前玩家的最后一个杠取消
                            targetPlayer.cancelLastGangForQG(card);

                            huPlayer.setRoundScoreRule(rule);
                        }
                    }
                    break;
                // 亮倒翻倍
                case Const.ScoreRule.BT:
                    huPlayer.setRoundScoreRule(rule);
                    break;
                default:
                    break;
            }
        }

        if (isZM) {
            huPlayer.setIsZm(isZM);
        }

        // 添加胡牌次数
        huPlayer.addHuCount();

        var huResult = isZM ? MJ.Result.ZM : MJ.Result.DH;
        huPlayer.setRoundResult(huResult, targetsIndex, card);

        huPlayer.setRoundPattern(pattern, patternScore);
        targets.forEach(function(target) {
            if (huResult != MJ.Result.ZM) {
                target.addDianHuCount();
            }
            target.setRoundResult(-huResult);
        });

        // 进行买马
        if (isZM) {
            this.buyMaInterface (huPlayer, card);
        }
    },

    onSettlement : function () {
        this._super();

        // 结算杠分
        this.settlementGangScore();

        // 计算每个玩家的具体小牌型
        this.enumPlayers(function (eIndex, ePlayer) {

            if (ePlayer) {
                // 计算每个玩家的杠分
                ePlayer.settlementGangScore();
            }
        });

        // 结算所有玩家的牌型分数以及漂数
        if (this.isRoundHZ()) {
            this.onSettlementHZ ();
        }else {

            this.enumPlayers( function (eIndex, ePlayer) {

                if (ePlayer && ePlayer.isRoundHu()) {
                    this.onSettlementHuCard (eIndex);
                }
            }.bind(this));
        }

        // 将玩家的分数进行总结算
        this.enumPlayers(function(eIndex, ePlayer) {

            if (ePlayer) {
                var settlementScore = ePlayer.getRoundItemScore();
                ePlayer.addRoundScore(settlementScore);
            }
        }.bind (this));
    },

    /******************************************************************
     * 操作接口
     ******************************************************************/

    handleSelectPiao : function (player, msg, callback) {

        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (!this.getOption("isAddPiao")) {
            callback({code: SubCode.PIAO_NOT_ALLOWED}); return;
        }

        if (player.isSelectPiao()) {
            callback({code: SubCode.PIAO_STATUS_ERROR}); return;
        }

        player.setSelectPiao(msg.piao);

        callback({});

        this.broadcastReplay("onPlayerSelectPiao", {
            playerIndex: player.getIndex(),
            piao: msg.piao
        });

        var isAllSelected = true;
        var results = {};
        this.enumPlayers(function(eIndex, ePlayer) {
            results[eIndex] = ePlayer.getSelectPiao();
            if (!ePlayer.isSelectPiao()) {
                isAllSelected = false;
            }
        });

        if (isAllSelected) {
            this.enumPlayers(function(eIndex, ePlayer) {
                ePlayer.send("onPlayerPiaoSelected", {"players": results});
            }.bind(this));

            this._piaoStatus = Const.PiaoStatus.Finish;
            this.preStartPlay();
        }
    }
});